package com.blue.base.oauth.server.config.authentic;

import com.blue.base.oauth.server.config.authentic.handler.MyLogoutHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * security 核心配置
 *
 * @author liulei
 * @version 1.0
 */
@Slf4j
@Component
@EnableWebSecurity
public class SecurityWebConfig extends WebSecurityConfigurerAdapter {

    /**=============================== 必须声明、重写的配置 ================================*/

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Autowired
    private MyLogoutHandler logoutHandler;

    /**
     * 用户授权之前，进行web登录认证的基础配置
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        // 登录、url过滤配置【建议开始的时候就配制好js、css、image图片的过滤，否则测试的时候总是出现奇怪的问题，一步到位咱】
        List<String> skipUrls = Arrays.asList("/oauth/**", "/login/**", "/logout/**", "/js/**", "/images/**", "/css/**");
        http.csrf()
                .disable()
                .authorizeRequests()
                .antMatchers(StringUtils.join(skipUrls, ",").split(",")).permitAll()
                // OPTIONS请求全部放行
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                // 默认拦截所有未登录的请求【一定要做注意放在antMatchers()之后，否则会拦截所有url】
                .anyRequest().authenticated()
                .and()
                // 使用页面登录
                .formLogin()
                .loginPage("/login")
                .and().logout().addLogoutHandler(logoutHandler).clearAuthentication(true)
                .permitAll();
    }

}
